package com.hk.yajin.utills;

import android.text.TextUtils;
import android.webkit.URLUtil;


import com.hk.developmentlib.baseben.NewWorkBean;
import com.hk.developmentlib.cache.SimpleDiskCache;
import com.hk.developmentlib.callback.HttpCallBack;
import com.hk.developmentlib.utills.CacheUtils;
import com.hk.developmentlib.utills.FastjsonUtils;
import com.hk.developmentlib.utills.StringHelper;
import com.hk.developmentlib.utills.des.Des;
import com.hk.yajin.base.MyApplication;

import org.xutils.common.Callback;
import org.xutils.common.util.LogUtil;
import org.xutils.http.HttpMethod;
import org.xutils.http.RequestParams;
import org.xutils.x;

import java.io.File;
import java.io.IOException;
import java.io.Serializable;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


/**
 * 网络请求工具类
 *
 * @author WL
 */
public class HttpRequestUtils {

    /**
     * get请求得到json数据
     *
     * @param startCache 是否启用缓存对象
     * @param url        接口地址,缓存的key
     * @param
     * @param callBack   回调
     * @param IsDecrypt  数据是否解密
     * @param
     */
    public static Callback.Cancelable get(final boolean startCache, final String url, Map<String, Object> body, final boolean IsDecrypt, final HttpCallBack callBack) {
        if (!URLUtil.isValidUrl(url) || callBack == null) {
            callBack.onBadHttp("请求地址异常");
            LogUtil.d("异常地址：" + url);
            return null;
        } else {
            String parmUrl = getParmUrl(IsDecrypt, body, url);
            if (startCache) {
                return handleCache(parmUrl, IsDecrypt, HttpMethod.GET, new RequestParams(parmUrl), callBack);
            } else {
                return execute(null, parmUrl, callBack, IsDecrypt, HttpMethod.GET, new RequestParams(parmUrl));
            }
        }
    }

    private static String getParmUrl(boolean IsDecrypt, Map<String, Object> body, String url) {
        if (body.keySet().size() == 0) {
            return url;
        }
        String cacheKey = url + "?";
        if (IsDecrypt) {
            String data = FastjsonUtils.toJSONString(body);
            data = StringHelper.getDESString(data);
            cacheKey += "data=" + data;
        } else {
            for (String key : body.keySet()) {
                if (!key.equals("loginkey")) {  //缓存的数据于loginkey不挂钩
                    cacheKey += key + "=" + body.get(key) + "&";
                }
            }
            if (cacheKey.endsWith("&")) {
                cacheKey = cacheKey.substring(0, cacheKey.length() - 1);
            }
        }
        return cacheKey;
    }


    /**
     * post请求得到json数据
     *
     * @param startCache 是否启用缓存
     * @param url        接口地址,缓存的key
     * @param
     * @param callBack   网络请求应答处理器
     * @param IsDecrypt  数据是否解密
     */
    public static Callback.Cancelable post(final boolean startCache, final String url, Map<String, Object> body, final boolean IsDecrypt, final HttpCallBack callBack
    ) {
        if (!URLUtil.isValidUrl(url) || body == null || callBack == null) {
            callBack.onBadHttp("地址异常或数据为空");
            LogUtil.d("异常地址：" + url);
            return null;
        } else {
            String parmUrl = getParmUrl(IsDecrypt, body, url);
            if (startCache) {
                return handleCache(url, parmUrl, IsDecrypt, HttpMethod.POST, getRequestParams(IsDecrypt, body, url), callBack);
            } else {
                return execute(null, url, parmUrl, callBack, IsDecrypt, HttpMethod.POST, getRequestParams(IsDecrypt, body, url));
            }
        }
    }


    protected static Callback.Cancelable handleCache(String key, boolean IsDecrypt, HttpMethod method, RequestParams params, HttpCallBack callBack) {
        return handleCache(key, key, IsDecrypt, method, params, callBack);
    }


    protected static Callback.Cancelable handleCache(String key, String postKey, boolean IsDecrypt, HttpMethod method, RequestParams params, HttpCallBack callBack) {
        SimpleDiskCache mDiskCache = CacheUtils.getInstance().getSimpleDiskCache();
        long interval = AppUtils.getCacheTime(MyApplication.getInstance());

        Map<String, Object> map = null;
        try {
            map = (Map<String, Object>) mDiskCache.getObject(postKey);
        } catch (Exception e) {
            LogUtil.e("", e);
            return execute(mDiskCache, postKey, callBack, IsDecrypt, method, params);
        }

        if (map != null) {
            String cacheJson = null;
            long cacheTime = 0;
            if (map.containsKey("data")) {
                cacheJson = map.get("data").toString();
            }
            if (map.containsKey("date")) {
                cacheTime = (Long) map.get("date");
            }
            if (interval == 0) { // 永久缓存，缓存优先
                if (cacheJson != null) {
                    NewWorkBean newWorkBean = FastjsonUtils.getBeanObject(cacheJson, NewWorkBean.class);
                    callBack.onSucced(newWorkBean.getData());
                    return null;
                } else {
                    callBack.onBadHttp("请求异常");
                    return null;
                }
            } else {
                long currentTime = System.currentTimeMillis();
                if (currentTime - cacheTime > interval) { // 缓存过期，回调发送请求
                    return execute(mDiskCache, key, postKey, callBack, IsDecrypt, method, params);
                } else {
                    if (cacheJson != null) {
                        NewWorkBean newWorkBean = (NewWorkBean) FastjsonUtils.getBeanObject(cacheJson, NewWorkBean.class);
                        callBack.onSucced(newWorkBean.getData());
                        return null;
                    } else { // 缓存为空，回调发送请求
                        return execute(mDiskCache, key, postKey, callBack, IsDecrypt, method, params);
                    }
                }
            }
        } else {
            return execute(mDiskCache, key, postKey, callBack, IsDecrypt, method, params);
        }
    }


    protected static RequestParams getRequestParams(boolean IsDecrypt, Map<String, Object> body, String url) {
        LogUtil.d("请求参数：" + FastjsonUtils.toJSONString(body));
        RequestParams params = new RequestParams(url);
        if (IsDecrypt) {
            String data = FastjsonUtils.toJSONString(body);
            data = StringHelper.getDESString(data);
            params.addBodyParameter("data", data);
        } else {

            for (String key : body.keySet()) {
                if (body.get(key) instanceof File) {
                    params.addBodyParameter(key, (File) body.get(key));
                } else {
                    params.addParameter(key, body.get(key));
                }
            }
        }
        return params;
    }


    /**
     * 缓存数据到磁盘
     *
     * @param key   键
     * @param value 值
     * @throws IOException
     */
    public static void setDiskCache(String key, String value, SimpleDiskCache mDiskCache) {
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("data", value);
        map.put("date", System.currentTimeMillis());
        try {
            mDiskCache.put(key, (Serializable) map);
        } catch (IOException e) {
            LogUtil.e("*存储出错！", e);
        }

    }

    /**
     * 发送请求
     *
     * @param mDiskCache
     * @param callBack
     * @param IsDecrypt
     * @param
     */
    private static Callback.Cancelable execute(final SimpleDiskCache mDiskCache, final String url, final HttpCallBack callBack,
                                               final boolean IsDecrypt, HttpMethod method, RequestParams params) {
        return execute(mDiskCache, url, url, callBack, IsDecrypt, method, params);
    }


    /**
     * 发送请求
     *
     * @param mDiskCache
     * @param callBack
     * @param IsDecrypt
     * @param
     */
    private static Callback.Cancelable execute(final SimpleDiskCache mDiskCache, final String url, final String urlkey, final HttpCallBack callBack,
                                               final boolean IsDecrypt, HttpMethod method, RequestParams params) {

        LogUtil.e("请求接口地址：---------->>>>:" + url);
        return x.http().request(method, params, new Callback.CommonCallback<String>() {


                    @Override
                    public void onCancelled(CancelledException cex) {

                    }

                    @Override
                    public void onFinished() {

                    }

                    @Override
                    public void onSuccess(String result) {
                        LogUtil.i("请求返回结果---------->>>>：" + result);
                        NewWorkBean newWorkBean = new NewWorkBean();
                        String str = null;
                        if (IsDecrypt) {
                            try {

                                str = Des.decryptDES(result, SimpleDiskCache.YJ_DES_KEY);
                                LogUtil.i("解密结果---------->>>>：" + String.valueOf(str));
                            } catch (Exception e2) {
                                LogUtil.e("错误原因：" + e2.getMessage());
                                newWorkBean.setCode(-1);
                                newWorkBean.setMsg("解密失败：" + e2.getMessage());
                                callBack.onErrorCode(newWorkBean);
                                return;
                            }
                        } else {
                            str = result;
                        }
                        if (!TextUtils.isEmpty(str) && str.startsWith("{") && str.endsWith("}")) {
                            newWorkBean = (NewWorkBean) FastjsonUtils.getBeanObject(str, NewWorkBean.class);
                            if (newWorkBean.getCode() == 0) {
                                String dataString = newWorkBean.getData();
                                if (!TextUtils.isEmpty(dataString) && mDiskCache != null) {
                                    setDiskCache(urlkey, str, mDiskCache);
                                }
                                callBack.onSucced(dataString);
                            } else {
                                callBack.onErrorCode(newWorkBean);
                            }

                        } else {
                            callBack.onBadHttp("数据格式存在问题");
                        }

                    }

                    @Override
                    public void onError(Throwable ex, boolean isOnCallback) {
                        callBack.onBadHttp(ex.getMessage());
                    }
                }

        );
    }
}
